package org.tamal.persistence;

import java.util.Set;

import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.DynamicUpdate;

/**
 * This represents a branch.
 * @author Tamal Kanti Nath
 */
@Entity
@Cacheable
@DynamicUpdate
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Branch {

    private Integer id;
    private String name;
    private String address;
    private Set<Account> accounts;
    private Set<Employee> employees;

    /**
     * Returns the id.
     * @return the id
     */
    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    /**
     * Sets the id.
     * @param id the id to set
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * Returns the name.
     * @return the name
     */
    @Column(nullable = false, unique = true)
    public String getName() {
        return name;
    }

    /**
     * Sets the name.
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Returns the address.
     * @return the address
     */
    @Column(nullable = false)
    public String getAddress() {
        return address;
    }

    /**
     * Sets the address.
     * @param address the address to set
     */
    public void setAddress(String address) {
        this.address = address;
    }

    /**
     * Returns the accounts.
     * @return the accounts
     */
    @OneToMany(mappedBy = "branch", cascade = CascadeType.ALL)
    public Set<Account> getAccounts() {
        return accounts;
    }

    /**
     * Sets the accounts.
     * @param accounts the accounts to set
     */
    public void setAccounts(Set<Account> accounts) {
        this.accounts = accounts;
    }

    /**
     * Returns the employees.
     * @return the employees
     */
    @OneToMany(mappedBy = "branch", cascade = CascadeType.ALL)
    public Set<Employee> getEmployees() {
        return employees;
    }

    /**
     * Sets the employees.
     * @param employees the employees to set
     */
    public void setEmployees(Set<Employee> employees) {
        this.employees = employees;
    }

    /**
     * Indicates whether the specified object equals to this object.<br/>
     * For Branch entity, the name is the business key. Two branches are
     * considered equal if their name are equal.
     *
     * @param obj the reference object with which to compare
     * @return if this Branch is the same as the obj argument; false otherwise
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Employee)) {
            return false;
        }
        return name.equals(((Branch) obj).name);
    }

    /**
     * The hash code is generated from name.
     * @return hash code value for branch
     */
    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public String toString() {
        return "Id: " + id + " name: " + name;
    }
}
